package br.org.acessobrasil.portal.persistencia;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import javax.persistence.NoResultException;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import br.org.acessobrasil.portal.modelo.ConteudoFormatado;
import br.org.acessobrasil.portal.modelo.ItemConteudo;
import br.org.acessobrasil.portal.modelo.Pagina;
import br.org.acessobrasil.portal.modelo.PalavraChave;
public class ItemConteudoDaoSpring extends SuperDao<ItemConteudo> {
	private static Logger logger = Logger.getLogger(ItemConteudoDaoSpring.class);
	private static ItemConteudoDaoSpring instance;

	public ItemConteudoDaoSpring(){
		logger.info("ItemConteudoDaoSpring instanciado");
		instance = this;
	}

	/**
	 * Salva e Indexa as palavras chave
	 */
	@Override
	public void create(ItemConteudo itemConteudo) throws Exception {
		//indexa as palavras chave
		indexarPalavrasChave(itemConteudo);
		
		//Salva
		super.create(itemConteudo);
	}
	
	public void update(ItemConteudo itemConteudo, String palavraChave) throws Exception {
		if(palavraChave!=null && !palavraChave.equals(itemConteudo.getPalavraChave())){
			//Listar as antigas e remover este item
			if(itemConteudo.getPalavraChave()!=null){
				removerPalavrasChave(itemConteudo);
			}
			//altera a palavra
			itemConteudo.setPalavraChave(palavraChave);
			//indexa as novas palavras chave
			indexarPalavrasChave(itemConteudo);	
		}else if(palavraChave==null){
			//Listar as antigas e remover este item
			if(itemConteudo.getPalavraChave()!=null){
				removerPalavrasChave(itemConteudo);
			}
			
			//altera a palavra
			itemConteudo.setPalavraChave(palavraChave);
		}else if(itemConteudo.getStSituacao()!='p'){
			//Listar as antigas e remover este item
			if(itemConteudo.getPalavraChave()!=null){
				removerPalavrasChave(itemConteudo);
			}
		}
		
		//atualiza
		super.update(itemConteudo);
	}
	

	/**
	 * Atualiza. Quando a situacao for diferente de publicado remove as palavras chave
	 */
	public void update(ItemConteudo itemConteudo) throws Exception {
		if(itemConteudo.getStSituacao()!='p'){
			//Listar as antigas e remover este item
			if(itemConteudo.getPalavraChave()!=null){
				removerPalavrasChave(itemConteudo);
			}
		}
		super.update(itemConteudo);
	}
	
	/**
	 * Lista de palavras chave para colocar na tela de busca
	 * @return lista de palavras chave
	 */
	public List<PalavraChave> listarPalavrasChave(){
		Query query = getEntityManager().createQuery("Select pc from PalavraChave pc order by pc.nome asc");
		List<PalavraChave> lista = query.getResultList();
		//ordenar por ocorrencia?
		
		return lista;
	}
	
	/**
	 * Remove as palavras chave do item
	 * @param itemConteudo
	 */
	private synchronized void removerPalavrasChave(ItemConteudo itemConteudo){
		if(itemConteudo.getPalavraChave()!=null){
			//loop por todas as palavras do item
			String palavras[] = itemConteudo.getPalavraChave().split(",");
			for(String palavra:palavras){
				palavra = palavra.trim();
				
				Query query = getEntityManager().createQuery("Select pc from PalavraChave pc where pc.nome=:nome");
				query.setParameter("nome",palavra);
				PalavraChave palavraChave = null;
				try{
					palavraChave = (PalavraChave)query.getSingleResult();
					logger.info("Antes: itens de " + palavra + " = " + palavraChave.getListItemConteudo().size());
					palavraChave.getListItemConteudo().remove(itemConteudo);
					logger.info("Depois: itens de " + palavra + " = " + palavraChave.getListItemConteudo().size());
					if(palavraChave.getListItemConteudo().size()==0){
						//remover tambem a palavra chave
						getEntityManager().remove(palavraChave);
					}
					getEntityManager().flush();
					logger.info("Palavra removida '"+ palavra + "' do item conteudo " + itemConteudo.getNuItemConteudo());
				}catch(NoResultException e){
					logger.warn("PalavraChave nao encontrada '" + palavra + "' ao remover.");
				}
			}
		}
	}
	/**
	 * Separa, guarda e indexa as palavras
	 * @param itemConteudo
	 */
	public synchronized void indexarPalavrasChave(ItemConteudo itemConteudo){
		if(itemConteudo.getStSituacao()=='p'){
			if(itemConteudo.getPalavraChave()!=null){
				//loop por todas as palavras
				String palavras[] = itemConteudo.getPalavraChave().split(",");
				for(String palavra:palavras){
					palavra = palavra.trim();
					Query query = getEntityManager().createQuery("Select pc from PalavraChave pc where pc.nome=:nome");
					query.setParameter("nome",palavra);
					PalavraChave palavraChave = null;
					try{
						palavraChave = (PalavraChave)query.getSingleResult();
						if(!palavraChave.getListItemConteudo().contains(itemConteudo)){
							palavraChave.getListItemConteudo().add(itemConteudo);
							logger.info("PalavraChave '" + palavra + "' item de conteudo adicionado a sua lista. nuItemConteudo=" + itemConteudo.getNuItemConteudo());
						}else{
							logger.info("PalavraChave item de conteudo nao adicionado a lista " + itemConteudo.getNuItemConteudo());
						}
					}catch(NoResultException e){
						//caso nao exista
						palavraChave = new PalavraChave();
						palavraChave.setNome(palavra);
						palavraChave.getListItemConteudo().add(itemConteudo);
						getEntityManager().persist(palavraChave);
						logger.info("PalavraChave criada " + palavra);
					}
				}
			}
		}
	}
	
	public ItemConteudo select(Long nu_item_conteudo) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
		return getEntityManager().find(ItemConteudo.class,nu_item_conteudo);
	}

	@SuppressWarnings("unchecked")
	public List<ItemConteudo> getListItemConteudo(long nu_conteudo) throws SQLException {
		return getEntityManager()
			.createQuery("Select i From ItemConteudo i where i.nu_conteudo=? order by i.dt_para_publicacao, i.dt_criacao, i.no_titulo, i.nu_versao")
			.setParameter(1,nu_conteudo)
			.getResultList();
	}

	public void apagar(ItemConteudo itemConteudo) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException {
		getEntityManager()
			.createQuery("Delete From " + ConteudoFormatado.class.getSimpleName() + " cf where cf.nu_item_conteudo = ?")
			.setParameter(1, itemConteudo.getNuItemConteudo())
			.executeUpdate();
		getEntityManager().remove(itemConteudo);
		logger.debug("ItemConteudo apagado " + itemConteudo.getNuItemConteudo());
	}

	@SuppressWarnings("unchecked")
	public List<ItemConteudo> getListaItemConteudoPorUsuario(long nu_usuario,Date dataCriacaoIni,Date dataCriacaoFim){
		Query query = getEntityManager().createQuery("from ItemConteudo c where " +
				"c.nu_usuario = ? and " +
				"c.dt_criacao > ? and " +
				"c.dt_criacao < ?" );
		query.setParameter(1, nu_usuario);
		query.setParameter(2, dataCriacaoIni);
		query.setParameter(3, dataCriacaoFim);
		return query.getResultList();
	}
	
	
	public List<ItemConteudo> getListItemConteudoDescPublicado(long int1, Connection con) {
		return null;
	}

	
	public List<ItemConteudo> getListItemConteudoPublicado(long nu_conteudo, Connection con) throws SQLException {
		return null;
	}

	
	public List<ItemConteudo> getListItemConteudoPublicado(long nu_conteudo,
			Connection con, Date dataIni, Date dataFim) {
		return null;
	}

	
	public List<ItemConteudo> getListItemConteudoPublicado(Pagina pagina, int i) {
		return null;
	}

	
	public List<ItemConteudo> getListItemConteudoDescPublicado(long nu_conteudo, Connection con, Date dataIni, Date dataFim) {
		return null;
	}

	public static ItemConteudoDaoSpring getInstance() {
		return instance;
	}
}
